package fileutils

import (
	"fmt"
	"github.com/pkg/sftp"
	"golang.org/x/crypto/ssh"
	"io"
	_ "log"
	"os"
)

type SFTPUtil struct {
	Host     string
	Port     int
	User     string
	Password string
}

func (s *SFTPUtil) NewSFTPUtil(host string, port int, user string, password string) *SFTPUtil {
	return &SFTPUtil{
		Host:     host,
		Port:     port,
		User:     user,
		Password: password,
	}
}

func (s *SFTPUtil) Connect() (*sftp.Client, error) {
	config := &ssh.ClientConfig{
		User: s.User,
		Auth: []ssh.AuthMethod{
			ssh.Password(s.Password),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	conn, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", s.Host, s.Port), config)
	if err != nil {
		return nil, err
	}

	client, err := sftp.NewClient(conn)
	if err != nil {
		conn.Close()
		return nil, err
	}

	return client, nil
}

// 将文件上传到 SFTP 服务器
func (s *SFTPUtil) UploadFileToSFTP(data []byte, remoteFilePath string) error {
	client, err := s.Connect()
	if err != nil {
		return err
	}
	defer client.Close()
	// 创建远程文件
	remoteFile, err := client.Create(remoteFilePath)
	if err != nil {
		return err
	}
	defer remoteFile.Close()

	// 将数据写入远程文件
	_, err = remoteFile.Write(data)
	if err != nil {
		return err
	}

	return nil
}

// 检查目录是否存在，如果不存在则创建目录
func (s *SFTPUtil) CreateDirIfNotExist(dir string) error {
	client, err := s.Connect()
	if err != nil {
		return err
	}
	defer client.Close()

	_, err = client.Stat(dir)
	if err == nil {
		// 目录已存在
		return nil
	}

	err = client.Mkdir(dir)
	if err != nil {
		return fmt.Errorf("无法创建目录: %s", err)
	}

	return nil
}

func (s *SFTPUtil) UploadFile(localPath string, remotePath string) error {
	client, err := s.Connect()
	if err != nil {
		return err
	}
	defer client.Close()

	localFile, err := os.Open(localPath)
	if err != nil {
		return err
	}
	defer localFile.Close()

	remoteFile, err := client.Create(remotePath)
	if err != nil {
		return err
	}
	defer remoteFile.Close()

	_, err = io.Copy(remoteFile, localFile)
	if err != nil {
		return err
	}

	return nil
}

func (s *SFTPUtil) DownloadFile(remotePath string, localPath string) error {
	client, err := s.Connect()
	if err != nil {
		return err
	}
	defer client.Close()

	remoteFile, err := client.Open(remotePath)
	if err != nil {
		return err
	}
	defer remoteFile.Close()

	localFile, err := os.Create(localPath)
	if err != nil {
		return err
	}
	defer localFile.Close()

	_, err = io.Copy(localFile, remoteFile)
	if err != nil {
		return err
	}

	return nil
}

func (s *SFTPUtil) DeleteFile(remotePath string) error {
	client, err := s.Connect()
	if err != nil {
		return err
	}
	defer client.Close()

	err = client.Remove(remotePath)
	if err != nil {
		return err
	}

	return nil
}
